iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
Mobile Development

SwiftUI 的大大小小系列 第 28

Day 28 - 在 SwiftUI 實作客製化 ToggleStyle

  • 分享至 

  • xImage
  •  

hero

前一天在第 27 天提到如何用 Toggle 並使用 .button 風格,但是我們發現了一個問題。

先改成 Checkbox 的樣式

在這個案例,換成系統提供的圖標來模擬 checkbox 的效果,可以發現 .button 樣式賦予 ON 狀態時一個淺色背景,而這個淺色背景並是無法消除的

struct ContentView: View {
    @State private var isOn = false

    var body: some View {
        VStack {
            Toggle(isOn: $isOn) {
                Image(systemName: isOn ? "checkmark.square" : "square")
                    .font(.system(size: 50))
            }
            .toggleStyle(.button)
            .tint(.blue)
            .padding()
            if isOn {
                Text("已開啟")
            }
            Spacer()
        }
    }
}

2801

實作客製化 ToggleStyle

這時候就需要自己客製化一個 ToggleStyle 來達到我們想要的效果,也就是沒有多餘的背景。

依照 ToggleStyle 這個 protocol 來實作 makeBody 如下:

struct CheckboxStyle: ToggleStyle {
    func makeBody(configuration: Configuration) -> some View {
        return configuration.label
            .foregroundStyle(.blue)
            .onTapGesture {
                configuration.isOn.toggle()
                    
            }
    }
}

使用時直接初始化一個即可:

struct ContentView: View {
    @State private var isOn = false

    var body: some View {
        VStack {
            Toggle(isOn: $isOn) {
                Image(systemName: isOn ? "checkmark.square" : "square")
                    .font(.system(size: 50))
            }
            .toggleStyle(CheckboxStyle())
            .padding()
            Spacer()
        }
    }
}

如果想要用 dot notation 使用,就需要擴張 ToogleStyle

extension ToggleStyle where Self == CheckboxStyle {
    static var checkboxStyle: CheckboxStyle { CheckboxStyle() }
}

套用時就可以改成這樣:

.toggleStyle(.checkboxStyle)

最後效果

2802

結語

以上,就是 ToggleStyle 的基本用法,那今天的 SwiftUI 大大小小就到這邊,明天見!

環境

  • Xcode 15

本篇使用到的 UI 元件和 modifiers 基本上沒有受到版本更新影響。若要在 Xcode 14 等環境下使用也是沒問題的。


上一篇
Day 27 - 在 SwiftUI 中使用 Toggle
下一篇
Day 29 - 在 SwiftUI 中使用 alert
系列文
SwiftUI 的大大小小30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言